package tiepbm.app.util.intent;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import tiepbm.app.store.activity.R;
import tiepbm.app.util.Log;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;

public class LaunchIntent {

	public static int mEnterAnim = R.anim.fade_in;
	public static int mExitAnim = R.anim.fade_out;
	public static boolean isLaunchIntentWithAnimation = false;

	/**
	 * This method is used to when you want to start activity (A) without extra
	 * data
	 * 
	 * @param context
	 *            :context of another activity (B) which start activity (A)
	 * @param className
	 *            :name of class of activity (A) is started
	 */
	public static <T> void start(Context context, Class<T> className) {
		start(context, className, Intent.FLAG_ACTIVITY_NEW_TASK, null);
	}

	/**
	 * This method is used to when you want to start activity (A) without extra
	 * data
	 * 
	 * @param context
	 *            :context of another activity (B) which start activity (A)
	 * @param className
	 *            :name of class of activity (A) is started
	 * @param flag
	 *            :flag of intent
	 * 
	 */
	public static <T> void start(Context context, Class<T> className, int flag) {
		start(context, className, flag, null);
	}

	/**
	 * This method is used to when you want to start activity (A) without extra
	 * data
	 * 
	 * @param context
	 *            :context of another activity (B) which start activity (A)
	 * @param className
	 *            :name of class of activity (A) is started
	 * @param bundle
	 *            :extra bundle
	 */
	public static <T> void start(Context context, Class<T> className,
			Bundle bundle) {
		start(context, className, -1, bundle);
	}

	/**
	 * This method is used to when you want to start activity (A) without extra
	 * data
	 * 
	 * @param context
	 *            :context of another activity (B) which start activity (A)
	 * @param className
	 *            :name of class of activity (A) is started
	 * @param flag
	 *            :flag of intent
	 * @param bundle
	 *            :extra bundle
	 */
	public static <T> void start(Context context, Class<T> className, int flag,
			Bundle bundle) {
		Intent iLaunch = new Intent(context, className);

		// set extra
		if (bundle != null) {
			iLaunch.putExtras(bundle);
		}

		// set flag
		if (flag != -1) {
			iLaunch.addFlags(flag);
		}

		context.startActivity(iLaunch);
		if (isLaunchIntentWithAnimation) {
			try {
				((Activity) context).overridePendingTransition(mEnterAnim,
						mExitAnim);
			} catch (ClassCastException ce) {
				Log.e(ce.toString());
			}
		}
	}

	/**
	 * Start activity for result
	 * 
	 * @param context
	 * @param className
	 * @param flag
	 * @param bundle
	 * @param requestCode
	 */
	public static <T> void startForResult(Activity activity,
			Class<T> className, int flag, Bundle bundle, int requestCode) {
		Intent iLaunch = new Intent(activity, className);

		// set extra
		if (bundle != null) {
			iLaunch.putExtras(bundle);
		}

		// set flag
		if (flag != -1) {
			iLaunch.addFlags(flag);
		}

		activity.startActivityForResult(iLaunch, requestCode);
		if (isLaunchIntentWithAnimation) {
			activity.overridePendingTransition(mEnterAnim, mExitAnim);
		}
	}

	public static <T> void startForResult(Activity activity,
			Class<T> className, int requestCode) {
		startForResult(activity, className, -1, null, requestCode);
	}

	public static <T> void startForResult(Activity activity,
			Class<T> className, int flag, int requestCode) {
		startForResult(activity, className, flag, null, requestCode);
	}

	public static <T> void startForResult(Activity activity,
			Class<T> className, Bundle bundle, int requestCode) {
		startForResult(activity, className, -1, bundle, requestCode);
	}

	/**
	 * This method is used to when you want to start activity (A) with extra
	 * data
	 * 
	 * @param context
	 *            : The context of another activity (B) which start activity (A)
	 * @param className
	 *            : The name of class of activity (A) is started
	 * @param name
	 *            : The name of extra data
	 * @param value
	 *            : The object data value
	 * @throws NullPointerException
	 */
	@Deprecated
	public static <T> void startWithExtra(Context context, Class<T> className,
			String name, Object value) throws NullPointerException {
		Intent iLaunch = new Intent(context, className);
		iLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		if (value instanceof Integer) {
			iLaunch.putExtra(name, (Integer) value);
		} else if (value instanceof String) {
			iLaunch.putExtra(name, value.toString());
		} else if (value instanceof Long) {
			iLaunch.putExtra(name, (Long) value);
		} else if (value instanceof Float) {
			iLaunch.putExtra(name, (Float) value);
		} else if (value instanceof Boolean) {
			iLaunch.putExtra(name, (Boolean) value);
		} else if (value instanceof Serializable) {
			iLaunch.putExtra(name, (Serializable) value);
		}
		context.startActivity(iLaunch);
		if (isLaunchIntentWithAnimation) {
			try {
				((Activity) context).overridePendingTransition(mEnterAnim,
						mExitAnim);
			} catch (ClassCastException ce) {
				Log.e(ce.toString());
			}
		}
	}

	/**
	 * Method is used to when you want to start activity (A) with array extra
	 * data
	 * 
	 * @param context
	 *            The context of another activity (B) which start activity (A)
	 * @param className
	 *            The name of class of activity (A) is started
	 * @param values
	 *            The hash map contain data value
	 * @throws NullPointerException
	 */
	@Deprecated
	public static <T> void startWithArrayExtra(Context context,
			Class<T> className, Map<String, Object> values)
			throws NullPointerException {

		Intent iLaunch = new Intent(context, className);
		iLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		for (Map.Entry<String, Object> entry : values.entrySet()) {
			String key = entry.getKey();
			Object value = entry.getValue();
			if (value instanceof Integer) {
				iLaunch.putExtra(key, (Integer) value);
			} else if (value instanceof String) {
				iLaunch.putExtra(key, value.toString());
			} else if (value instanceof Long) {
				iLaunch.putExtra(key, (Long) value);
			} else if (value instanceof Float) {
				iLaunch.putExtra(key, (Float) value);
			} else if (value instanceof Boolean) {
				iLaunch.putExtra(key, (Boolean) value);
			} else if (value instanceof Serializable) {
				iLaunch.putExtra(key, (Serializable) value);
			}
		}
		context.startActivity(iLaunch);
		if (isLaunchIntentWithAnimation) {
			try {
				((Activity) context).overridePendingTransition(mEnterAnim,
						mExitAnim);
			} catch (ClassCastException ce) {
				Log.e(ce.toString());
			}
		}
	}

	/**
	 * Find launch intent of activity by package name
	 * 
	 * @param activity
	 *            The activity is used to get package manager to find launch
	 *            intent
	 * @param packageName
	 *            : The name of the package to inspect.
	 * @return Return a "good" intent to launch a front-door activity in a
	 *         package or null
	 */
	public static Intent findIntent(Context context, String packageName) {
		if (context == null || TextUtils.isEmpty(packageName)) {
			return null;
		}

		PackageManager packageManager = context.getPackageManager();

		List<ApplicationInfo> packages = packageManager
				.getInstalledApplications(PackageManager.GET_META_DATA);
		for (ApplicationInfo info : packages) {
			String name = info.packageName;
			if (name.equalsIgnoreCase(packageName)) {
				return packageManager.getLaunchIntentForPackage(name);
			}
		}
		return null;
	}

	/**
	 * Start activity when known package name of this activity
	 * 
	 * @param activity
	 *            activity used to start
	 * @param packageName
	 *            package name of activity is started
	 */
	public static void startByPackageName(Activity activity, String packageName) {
		Intent iLaunchApp = findIntent(activity, packageName);
		if (iLaunchApp != null) {
			iLaunchApp.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			activity.startActivity(iLaunchApp);
			if (isLaunchIntentWithAnimation) {
				activity.overridePendingTransition(mEnterAnim, mExitAnim);
			}
		}
	}

	/**
	 * Reset animation which used to switch activity
	 */
	public static void resetAnim() {
		mEnterAnim = R.anim.fade_in;
		mExitAnim = R.anim.fade_out;
		isLaunchIntentWithAnimation = false;
	}
	
	/**
	 * Send text to other application to share
	 * Open dialog chooser if more applications can share text
	 */ 
	public static void shareText(Activity activity, String content) {
		Intent sendIntent = new Intent();
		sendIntent.setAction(Intent.ACTION_SEND);
		sendIntent.putExtra(Intent.EXTRA_TEXT, content);
		sendIntent.setType("text/plain");
		activity.startActivity(sendIntent);
	}
	
	/**
	 * Send file to other application to share
	 * Open dialog chooser if more applications can share this mime type
	 */
	public static void shareFile(Activity activity, Uri fileUri, String mimeType) {
		Intent shareIntent = new Intent();
		shareIntent.setAction(Intent.ACTION_SEND);
		shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
		shareIntent.setType(TextUtils.isEmpty(mimeType) ? "*/*" : mimeType);
		activity.startActivity(shareIntent);
	}
	
	/**
	 * Send file to other application to share
	 * Open dialog chooser if more applications can share this file
	 */
	public static void shareFile(Activity activity, Uri fileUri) {
		shareFile(activity, fileUri, "");
	}
	
	/**
	 * Send image to other application to share
	 * Open dialog chooser if more applications can share image
	 */
	public static void shareImage(Activity activity, Uri imageUri) {
		shareFile(activity, imageUri, "image/*");
	}
	
	/**
	 * Send audio to other application to share
	 * Open dialog chooser if more applications can share audio
	 */
	public static void shareAudio(Activity activity, Uri audioUri) {
		shareFile(activity, audioUri, "audio/*");
	}
	
	/**
	 * Send video to other application to share
	 * Open dialog chooser if more applications can share video
	 */
	public static void shareVideo(Activity activity, Uri videoUri) {
		shareFile(activity, videoUri, "video/*");
	}
	
}
